<template>
  <div class="het-panel" style="margin-bottom: 10px">
    <div class="flex" style="width: 50%">
      <el-input v-model="keywords" placeholder="搜索关键字" style="width: 280px; margin-right: 15px" prefix-icon="Search" @keyup.enter="search"></el-input>
      <!-- <el-date-picker v-model="timeRange" type="datetimerange" range-separator="-" start-placeholder="开始时间" end-placeholder="结束时间" /> -->
    </div>
  </div>
  <div class="flex jcsb">
    <div class="het-panel" style="width: 49.5%">
      <h3 class="d-title">修复率统计</h3>
      <div class="flex jcc fix-box">
        <el-progress type="dashboard" :percentage="fixLv.all">
          <template #default="{ percentage }">
            <span class="percentage-value">{{ percentage }}%</span>
            <span class="percentage-label">整体</span>
          </template>
        </el-progress>
        <el-progress type="dashboard" :percentage="fixLv.h">
          <template #default="{ percentage }">
            <span class="percentage-value">{{ percentage }}%</span>
            <span class="percentage-label">高危及以上</span>
          </template>
        </el-progress>
        <el-progress type="dashboard" :percentage="fixLv.l">
          <template #default="{ percentage }">
            <span class="percentage-value">{{ percentage }}%</span>
            <span class="percentage-label">低危及以上</span>
          </template>
        </el-progress>
      </div>
    </div>
    <div class="het-panel" style="width: 49.5%">
      <h3 class="d-title">漏洞数统计</h3>
      <div class="flex jcsb">
        <div class="statistic-card">
          <el-statistic :value="eveCount?.totalCount">
            <template #title>
              <div style="display: inline-flex; align-items: center">漏洞总数</div>
            </template>
          </el-statistic>
          <div class="statistic-footer">
            <div class="footer-item">
              <span>今日新增</span>
              <span class="green">
                {{ eveCount?.todayCount }}
                <el-icon>
                  <CaretTop />
                </el-icon>
              </span>
            </div>
          </div>
        </div>

        <div class="count-box">
          <el-progress type="circle" width="100" :percentage="eveCount?.serCount">
            <template #default="{ percentage }">
              <span class="percentage-value">{{ percentage }}</span>
              <span class="percentage-label">严重</span>
            </template>
          </el-progress>
          <el-progress type="circle" width="100" :percentage="eveCount?.highCount">
            <template #default="{ percentage }">
              <span class="percentage-value">{{ percentage }}</span>
              <span class="percentage-label">高危</span>
            </template>
          </el-progress>
          <el-progress type="circle" width="100" :percentage="eveCount?.mediumCount">
            <template #default="{ percentage }">
              <span class="percentage-value">{{ percentage }}</span>
              <span class="percentage-label">中危</span>
            </template>
          </el-progress>
          <el-progress type="circle" width="100" :percentage="eveCount?.lowCount + eveCount?.infoCount">
            <template #default="{ percentage }">
              <span class="percentage-value">{{ percentage }}</span>
              <span class="percentage-label">低危</span>
            </template>
          </el-progress>
        </div>
      </div>
    </div>
  </div>
  <div class="het-panel" style="margin-top: 15px; position: relative">
    <HETTable ref="hetTable" :config="tableConfig" @finishDel="getEveCount()">
      <template #ctrlBtn>
        <el-dropdown trigger="click">
          <el-button type="primary" icon="Edit" style="margin-right: 10px">修改状态</el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="setVulnStatus('待处理')">待处理</el-dropdown-item>
              <el-dropdown-item @click="setVulnStatus('处理中')"> 处理中 </el-dropdown-item>
              <el-dropdown-item @click="setVulnStatus('已修复')">已修复</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </template>
    </HETTable>
    <el-dialog :title="isDetail ? '漏洞详情' : '漏洞上传'" v-model="dialogVisible" width="900px" @close="resetForm">
      <HETForm1 ref="formRef" v-model="formData" :formConfig="formConfig"></HETForm1>

      <template #footer v-if="!isDetail">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitVuln(formRef)">确 定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { onMounted, ref, computed, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { mAxios, encodeURL } from '~/utils/axios/axios.js'
import { reactify } from '@vueuse/core'
import moment from 'moment'
const dialogVisible = ref(false)
const isDetail = ref(false)
const keywords = ref('')
const search = () => {
  hetTable.value.getTableData({ keywords: keywords.value })
}
const hetTable = ref()
const tableConfig = ref({
  module: '',
  selectApi: params =>
    mAxios.get('vuln', {
      params
    }),
  deleteApi: params => mAxios.delete('vuln', { data: params }),
  search: {
    form: {},
    config: [
      {
        label: '',
        prop: 'cveId',
        type: 'input',
        style: { width: '160px' },
        setting: { placeholder: 'CVE' }
      },
      {
        label: '',
        prop: 'vulnName',
        type: 'input',
        style: { width: '160px' },
        setting: { placeholder: '漏洞名称' }
      },
      {
        label: '',
        prop: 'vulnType',
        type: 'select',
        style: { width: '160px' },
        setting: { placeholder: '漏洞类型' },
        options: [
          { label: '系统漏洞', value: '系统漏洞' },
          { label: '数据库漏洞', value: '数据库漏洞' },
          { label: '应用漏洞', value: '应用漏洞' }
        ]
      },
      {
        label: '',
        prop: 'severity',
        type: 'select',
        style: { width: '160px' },
        setting: { placeholder: '漏洞等级' },
        options: [
          { label: '严重', value: 'SERIOUS' },
          { label: '高危', value: 'HIGH' },
          { label: '中危', value: 'MEDIUM' },
          { label: '低危', value: 'LOW' },
          { label: '信息', value: 'INFO' }
        ]
      },
      {
        label: '',
        prop: 'status',
        type: 'select',
        style: { width: '160px' },
        setting: { placeholder: '漏洞状态' },
        options: [
          { label: '待处理', value: '待处理' },
          { label: '处理中', value: '处理中' },
          { label: '已修复', value: '已修复' }
        ]
      },
      {
        label: '',
        prop: 'timeRange',
        type: 'date-picker',
        setting: {
          type: 'datetimerange',
          rangeSeparator: '到',
          startPlaceholder: '开始时间',
          endPlaceholder: '结束时间'
        }
      }
    ]
  },
  columns: [
    { type: 'selection', width: 34 },
    // {
    //   label: 'CVE',
    //   prop: 'cveId'
    // },
    {
      label: '漏洞名称',
      prop: 'vulnName'
    },
    {
      label: '描述',
      prop: 'description',
      width: 300
    },
    // {
    //   label: "影响产品",
    //   prop: "affectedProduct",
    // },
    {
      label: '漏洞类型',
      prop: 'vulnType'
    },
    {
      label: '漏洞等级',
      prop: 'severity',
      formatter: row => {
        switch (row.severity) {
          case 'INFO':
            return '信息'
          case 'LOW':
            return '低危'
          case 'MEDIUM':
            return '中危'
          case 'HIGH':
            return '高危'
          default:
            return '严重'
        }
      }
    },
    {
      label: 'cvss评分',
      prop: 'baseScore'
    },
    {
      label: '漏洞状态',
      prop: 'status'
    },
    {
      label: '漏洞来源',
      prop: 'origin'
    },
    {
      label: '发现时间',
      prop: 'publishTime',
      width: 200
    },
    {
      label: '操作',
      custom: {
        type: 'button',
        operatBtns: [
          {
            name: '详情',
            handleClick: row => {
              formData.value = row
              isDetail.value = true
              dialogVisible.value = true
            }
          },
          {
            name: '删除',
            type: 'delete'
          }
        ]
      }
    }
  ],
  controlBtns: [
    {
      name: '修改状态',
      icon: 'Edit',
      type: 'slot'
    },
    {
      name: '上传漏洞',
      icon: 'Plus',
      type: 'primary',
      handleClick: () => {
        dialogVisible.value = true
        isDetail.value = false
      }
    },
    {
      name: '批量删除',
      icon: 'Delete',
      type: 'delete',
      disabled: data => {
        return data.length == 0
      }
    }
  ]
})

const eveCount = ref(null)
const fixLv = reactive({
  all: 0,
  h: 0,
  l: 0
})
const getEveCount = () => {
  mAxios.get('vuln/eve/count').then(res => {
    let data = res.data.data
    eveCount.value = data
    if (data?.totalCount > 0) fixLv.all = ((data?.fixCount / data?.totalCount) * 100).toFixed(1)
    if (data?.highCount + data?.serCount > 0) fixLv.h = ((data?.fixCount / (data?.highCount + data?.serCount)) * 100).toFixed(1)
    if (data?.totalCount - data?.lowCount > 0) fixLv.l = ((data?.fixCount / (data?.totalCount - data?.lowCount)) * 100).toFixed(1)
  })
}
onMounted(() => {
  getEveCount()
})

const setVulnStatus = status => {
  if (hetTable.value.selectData.length == 0) {
    ElMessage.error('请选择要处理的漏洞')
    return
  }
  let ids = hetTable.value.selectData.map(item => item.id)
  mAxios.put('vuln/status', { ids, status }).then(res => {
    res.data.succeed ? ElMessage.success('设置成功') : ElMessage.error('设置失败')
    hetTable.value.getTableData()
    getEveCount()
  })
}

const formRef = ref()
const formData = ref({ status: '待处理' })
const formConfig = [
  {
    label: '漏洞名称',
    prop: 'vulnName',
    type: 'input',
    required: true
  },
  {
    label: 'CVE',
    prop: 'cveId',
    type: 'input'
    // required: true
  },
  {
    label: '描述',
    prop: 'description',
    type: 'input',
    setting: { type: 'textarea' }
  },
  {
    label: '漏洞影响',
    prop: 'affectedProduct',
    type: 'input',
    setting: { type: 'textarea' }
  },
  {
    label: '漏洞类型',
    prop: 'vulnType',
    type: 'input',
    required: true
  },
  {
    label: '危害等级',
    prop: 'severity',
    type: 'select',
    required: true,
    options: [
      { label: '严重', value: 'SERIOUS' },
      { label: '高危', value: 'HIGH' },
      { label: '中危', value: 'MEDIUM' },
      { label: '低危', value: 'LOW' },
      { label: '信息', value: 'INFO' }
    ]
  },
  {
    label: '状态',
    prop: 'status',
    type: 'select',
    options: [
      { label: '待处理', value: '待处理' },
      { label: '处理中', value: '处理中' },
      { label: '已修复', value: '已修复' }
    ]
  },
  {
    label: 'cvss评分',
    prop: 'baseScore',
    type: 'input'
  },
  {
    label: '修复建议',
    prop: 'suggestion',
    type: 'input',
    setting: { type: 'textarea' }
  },
  {
    label: '参考信息',
    prop: 'reference',
    type: 'input',
    setting: { type: 'textarea' }
  }
]
const resetForm = () => {
  formData.value = { status: '待处理' }
  formRef.value.resetFields()
}

const submitVuln = formEl => {
  formEl.validate(valid => {
    if (valid) {
      const params = {
        ...formData.value,
        origin: '用户上传',
        publishTime: moment().format('YYYY-MM-DD HH:mm:ss')
      }
      mAxios.post('vuln/add', params).then(res => {
        res.data.succeed ? ElMessage.success('操作成功') : ElMessage.error('操作失败')
        dialogVisible.value = false
        hetTable.value.getTableData()
      })
    }
  })
}
</script>

<style lang="scss" scoped>
// .svd {
//   position: absolute;
//   top: 20px;
//   left: 30px;
// }
.d-title {
  font-size: 16px;
  color: #000;
  font-weight: 600;
  margin-bottom: 15px;
}
.fix-box .el-progress {
  margin: 0 40px;
  .percentage-value {
    font-size: 18px;
    color: #000;
    font-weight: 600;
  }
  .percentage-label {
    font-size: 14px;
    margin-top: 6px;
  }
}
.count-box .el-progress {
  margin-left: 30px;
  .percentage-value {
    font-size: 18px;
    color: #000;
    font-weight: 600;
  }
  .percentage-label {
    font-size: 14px;
    margin-top: 6px;
  }
}
.el-progress__text span {
  display: block;
}
:global(h2#card-usage ~ .example .example-showcase) {
  background-color: var(--el-fill-color) !important;
}

.el-statistic {
  --el-statistic-content-font-size: 28px;
}

.statistic-card {
  height: 100%;
  padding: 8px;
  border-radius: 4px;
  background-color: var(--el-bg-color-overlay);
}

.statistic-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--el-text-color-regular);
  margin-top: 16px;
}

.statistic-footer .footer-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.statistic-footer .footer-item span:last-child {
  display: inline-flex;
  align-items: center;
  margin-left: 4px;
}

.green {
  color: var(--el-color-success);
}
.red {
  color: var(--el-color-error);
}
</style>
